import { routerRedux } from 'dva/router';
import _ from 'lodash';
import * as imService from '../services/imService';
import * as vipService from '../services/vipService';

const VIP_AVATAR = 'http://wx.hy-bang.com/im/vip_avatar.png';
const SALEMAN_AVATAR = 'http://wx.hy-bang.com/im/saleman_avatar.png';

const delay = (time) => {
  return new Promise((rs) => {
    setTimeout(rs, time);
  });
};

export default {
  namespace: 'im',
  state: {
    sender: {},
    targetList: [],
    target: {},
    chatList: [],
    chatMessages: [],
    imInit: false,
    pathname: '',
    newMessage: false,
  },
  effects: {
    * init({ payload }, { call, put, select }) {
      yield delay(2000);
      const { imInit } = yield select(state => state.im);
      if (imInit) {
        return;
      }
      const { shopId, salemanId } = yield select(state => state.auth.currentUser);
      if (shopId && salemanId) {
        const sender = (yield call(imService.fetchSalemanImUser, shopId, salemanId)).data;
        // 给导购发送过信息的用户
        const senders = sender.senders || [];
        const targetList = (yield call(imService.fetchImUsers, shopId, { filter: { userId: { $in: senders } }, sort: { updatedAt: -1 } })).data;
        let chatList = [];
        if (targetList && targetList.length) {
          for (const targetUser of targetList) {
            const message = (yield call(imService.fetchImMessages, shopId, {
              page: 1,
              pageSize: 1,
              sort: { sendTime: -1 },
              filter: { $or: [{ targetId: sender.userId, senderId: targetUser.userId }, { senderId: sender.userId, targetId: targetUser.userId }] },
            })).data[0] || null;
            chatList.push({
              avatar: VIP_AVATAR,
              sender: targetUser,
              message,
              sendTime: message ? message.sendTime : '',
              imUserId: targetUser.userId,
            });
          }
        }

        // 未给导购发送过信息的用户
        const userList = (yield call(imService.fetchImUsers, shopId,
          {
            filter: { vipQuery: { filter: { saleman_id: salemanId }, page: 1, pageSize: 2500, sort: { card_bind_time: -1 } } },
            sort: { updatedAt: -1 },
          })).data;
        if (userList && userList.length) {
          for (const targetUser of userList) {
            if (!_.includes(senders, targetUser.userId)) {
              targetList.push(targetUser);
              chatList.push({
                avatar: VIP_AVATAR,
                sender: targetUser,
                sendTime: '',
                imUserId: targetUser.userId,
              });
            }
          }
        }

        chatList = _.sortBy(chatList, (item) => {
          return item.sendTime;
        });
        yield put({ type: 'update', payload: { sender, chatList, targetList } });
        yield put({ type: 'initIM', payload: { shopId, sender }, quiet: true });
      }
    },
    * initIM({ payload }, { call, put, select }) {
      const { sender } = payload;
      yield imService.initIMClient(sender.imToken, (type, content, message) => {
        const app = window.app;
        if (app && app._store) {
          app._store.dispatch({
            type: 'im/receiveNewMessage',
            payload: { type, content, message },
          });
        }
      });
      yield put({ type: 'update', payload: { imInit: true } });
    },
    * receiveNewMessage({ payload }, { call, put, select }) {
      const { sender, target, chatMessages, pathname, chatList } = yield select(state => state.im);
      const { type, content, message } = payload;
      if (type && content) {
        let unread = false;
        if (pathname !== 'imChatMessage') {
          unread = true;
          yield put({ type: 'update', payload: { newMessage: true } });
        } else {
          yield put({ type: 'update', payload: { newMessage: false } });
        }
        const newMessage = {
          unread,
          type,
          senderId: message.senderUserId,
          targetId: sender.userId,
          content,
          sendTime: new Date(),
        };
        yield put({ type: 'update', payload: { chatMessages: [...chatMessages, newMessage] } });
        const newChatList = _.map(chatList, (chat) => {
          if (chat.sender && chat.sender.userId === message.senderUserId) {
            chat.message = newMessage;
          }
          return chat;
        });
        yield put({ type: 'update', payload: { chatList: newChatList } });
      }
    },
    * toChatMessage({ payload }, { call, put, select }) {
      const { shopId } = yield select(state => state.auth.currentUser);
      const { sender, targetList } = yield select(state => state.im);
      const { card_no } = payload;
      if (sender && shopId && card_no) {
        const vip = (yield call(vipService.fetchVipInfo, shopId, payload.card_no)).data;
        const target = _.find(targetList, (targetItem) => {
          return targetItem.card_no === card_no;
        });
        let chatMessages = [];
        if (target) {
          chatMessages = (yield imService.fetchImMessages(shopId, {
            filter: {
              $or: [
                {
                  senderId: sender.userId,
                  targetId: target.userId,
                },
                {
                  targetId: sender.userId,
                  senderId: target.userId,
                },
              ],
            },
            sort: { sendTime: -1 },
          })).data || [];
        }
        chatMessages = _.reverse(chatMessages);
        yield put({ type: 'update', payload: { vip, target, chatMessages } });
      }
      yield put(routerRedux.push({
        pathname: '/imChatMessage',
        query: {
          shopId,
          card_no: payload.card_no,
        },
      },
      ));
    },
    * sendMessage({ payload }, { call, put, select }) {
      const { shopId } = yield select(state => state.auth.currentUser);
      const { sender, target, chatMessages = [] } = yield select(state => state.im);
      const { type, content } = payload;
      const message = (yield imService.createImMessage(shopId, {
        type,
        content,
        senderId: sender.userId,
        targetId: target.userId,
      })).data;
      yield put({ type: 'update', payload: { chatMessages: [...chatMessages, message] } });
    },
    * pathChange({ payload }, { call, put, select }) {
      const pathname = payload.pathname;
      const payloadData = {
        pathname,
      };
      if (pathname === '/imChatMessage') {
        payloadData.newMessage = false;
      }
      yield put({
        type: 'update',
        payload: payloadData,
      });
    },
    * readMessage({ payload }, { call, put, select }) {
      const { shopId } = yield select(state => state.auth.currentUser);
      const { messageIds } = payload;
      yield imService.readImMessage(shopId, messageIds);
    },
  },
  reducers: {
    update(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
  subscriptions: {
    setup({ dispatch, history }) {
      return history.listen(({ pathname, query }) => {
        if (pathname === '/' || pathname === '/imChatList') {
          dispatch({
            type: 'init',
            payload: {},
          });
        }
        dispatch({
          type: 'pathChange',
          payload: { pathname },
        });
      });
    },
  },
};
